﻿Imports System.Data
Imports System.Configuration
Imports System.Collections
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Net
Imports System.IO
Imports System.Text

Partial Public Class ReCaptchaControl
    Inherits System.Web.UI.UserControl
    Private m_privateKey As String
    Private m_publicKey As String

    Private m_validated As Boolean = False
    Private m_errorMessage As String = ""


    Public Property PrivateKey() As String
        Get
            Return Me.m_privateKey
        End Get
        Set(value As String)
            Me.m_privateKey = value
        End Set
    End Property

    Public Property PublicKey() As String
        Get
            Return Me.m_publicKey
        End Get
        Set(value As String)
            Me.m_publicKey = value
        End Set
    End Property

    Public ReadOnly Property Validated() As Boolean
        Get
            Return Me.m_validated
        End Get
    End Property

    Public ReadOnly Property ErrorMessage() As String
        Get
            Return Me.m_errorMessage
        End Get
    End Property

    Protected Sub Page_Load(sender As Object, e As EventArgs)
        If Page.IsPostBack Then
            Dim challengeValue As String = Request.Form("recaptcha_challenge_field")
            Dim responseValue As String = Request.Form("recaptcha_response_field")
            Me.m_validated = Me.verifyReCaptcha(challengeValue, responseValue)
            MsgBox("2")
        End If

        If Not Page.IsPostBack OrElse Not Me.m_validated Then
            lblReCaptcha.Text = String.Format("", Me.m_publicKey)

            MsgBox("1")
        End If
    End Sub

    Private Function verifyReCaptcha(ChallengeValue As String, ResponseValue As String) As Boolean
        'Sanity check
        If ChallengeValue = "" OrElse ResponseValue = "" Then
            Return False
        End If

        'Create the postdata
        Dim postData As String = [String].Format("privatekey={0}&remoteip={1}&challenge={2}&response={3}", Me.m_privateKey, HttpContext.Current.Request.UserHostAddress, ChallengeValue, ResponseValue)

        Dim postDataBuffer As Byte() = Encoding.ASCII.GetBytes(postData)

        Dim responseValues As String() = New String() {}
        Dim success As Boolean = False
        Dim attempt As Integer = 0

        While Not success AndAlso attempt <= 3
            Try
                responseValues = getResponseValues(postDataBuffer)
                success = True
            Catch
                attempt += 1
                success = False
            End Try
        End While

        If success Then
            Dim verified As Boolean = (responseValues(0) = "true")

            If Not verified Then
                Me.m_errorMessage = responseValues(1)
            Else
                Me.m_errorMessage = ""
            End If

            Return verified
        Else
            Me.m_errorMessage = "The ReCaptcha server could not be contacted"
            Return False
        End If
    End Function

    Private Function getResponseValues(PostDataBuffer As Byte()) As String()
        'Build the request
        Dim verificationRequest As HttpWebRequest = DirectCast(WebRequest.Create("http://api-verify.recaptcha.net/verify"), HttpWebRequest)

        verificationRequest.Method = "POST"
        verificationRequest.ContentType = "application/x-www-form-urlencoded"
        verificationRequest.ContentLength = PostDataBuffer.Length
        verificationRequest.ServicePoint.Expect100Continue = False

        'Get the request stream and write the postdata to it
        Dim verificationRequestStream As Stream = verificationRequest.GetRequestStream()
        verificationRequestStream.Write(PostDataBuffer, 0, PostDataBuffer.Length)
        verificationRequestStream.Close()

        'Get the response
        Dim verificationResponse As HttpWebResponse = DirectCast(verificationRequest.GetResponse(), HttpWebResponse)
        Dim verificationResponseReader As New StreamReader(verificationResponse.GetResponseStream(), Encoding.ASCII)

        Dim splitter As Char() = New Char() {ControlChars.Lf}
        Dim responseValues As String() = verificationResponseReader.ReadToEnd().Split(splitter)

        verificationResponseReader.Close()
        verificationRequestStream.Close()

        Return responseValues
    End Function
End Class
